package logic

import (
	"context"
	"time"

	"probe-users/internal/errorx"
	"probe-users/internal/svc"
	"probe-users/internal/utils"
	"probe-users/pb/users"

	"probe-users/internal/model"

	"github.com/pkg/errors"
	"github.com/zeromicro/go-zero/core/logx"
)

type RegisterLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

func NewRegisterLogic(ctx context.Context, svcCtx *svc.ServiceContext) *RegisterLogic {
	return &RegisterLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

func (l *RegisterLogic) Register(in *users.RegisterRequest) (*users.RegisterResponse, error) {
	// 检查注册功能是否开启
	if !l.svcCtx.Config.User.RegisterEnabled {
		return nil, errorx.ErrRegisterDisabled
	}

	// 参数验证(用户名和密码)
	if err := l.validateRegisterParams(in); err != nil {
		return nil, err
	}

	// 检查用户名是否已存在
	_, err := l.svcCtx.UserModel.FindByUsername(in.Username)
	if err == nil {
		// 如果没有错误，说明找到了用户，即用户名已存在
		return nil, errorx.ErrUsernameExists
	}
	// 如果错误不是"用户不存在"，则返回错误
	if !errors.Is(err, errorx.ErrUserNotFound) {
		return nil, errors.Wrapf(err, "查询用户失败: %s", in.Username)
	}

	// 检查邮箱是否已存在
	if in.Email != "" {
		_, err := l.svcCtx.UserModel.FindByEmail(in.Email)
		if err == nil {
			// 如果没有错误，说明找到了邮箱，即邮箱已存在
			return nil, errorx.ErrEmailExists
		}
		// 如果错误不是"用户不存在"，则返回错误
		if !errors.Is(err, errorx.ErrUserNotFound) {
			return nil, errors.Wrapf(err, "查询邮箱失败: %s", in.Email)
		}
	}

	// 检查手机号是否已存在
	if in.Phone != "" {
		_, err := l.svcCtx.UserModel.FindByPhone(in.Phone)
		if err == nil {
			// 如果没有错误，说明找到了手机号，即手机号已存在
			return nil, errorx.ErrPhoneExists
		}
		// 如果错误不是"用户不存在"，则返回错误
		if !errors.Is(err, errorx.ErrUserNotFound) {
			return nil, errors.Wrapf(err, "查询手机号失败: %s", in.Phone)
		}
	}

	// 密码加密
	hashedPassword, err := utils.HashPassword(in.Password)
	if err != nil {
		return nil, errors.Wrapf(err, "密码加密失败")
	}

	// 获取默认角色（普通用户）
	defaultRole, err := l.svcCtx.RoleModel.FindByName("user")
	if err != nil {
		return nil, errors.Wrapf(err, "获取默认角色失败")
	}

	// 创建用户
	now := time.Now()
	user := &model.User{
		Username:  in.Username,
		Password:  hashedPassword,
		Email:     in.Email,
		Phone:     in.Phone,
		Nickname:  in.Nickname,
		RoleID:    defaultRole.ID,
		CreatedAt: now,
		UpdatedAt: now,
	}

	result, err := l.svcCtx.UserModel.Insert(user)
	if err != nil {
		return nil, errors.Wrapf(err, "创建用户失败")
	}

	// 获取插入的用户ID
	userID, err := result.LastInsertId()
	if err != nil {
		return nil, errors.Wrapf(err, "获取用户ID失败")
	}
	user.ID = userID

	// 生成Token
	token, err := utils.GenerateToken(
		user.ID,
		user.Username,
		user.RoleID,
		l.svcCtx.Config.JWTAuth.AccessSecret,
		l.svcCtx.Config.JWTAuth.AccessExpire,
	)
	if err != nil {
		return nil, errors.Wrapf(err, "生成token失败")
	}

	return &users.RegisterResponse{
		Id:       user.ID,
		Username: user.Username,
		Token:    token,
	}, nil
}

func (l *RegisterLogic) validateRegisterParams(in *users.RegisterRequest) error {
	if in.Username == "" {
		return errorx.ErrUsernameNotEmpty
	}
	if len(in.Username) < 3 || len(in.Username) > 20 {
		return errorx.ErrUsernameLengthInvalid
	}
	if in.Password == "" {
		return errorx.ErrPasswordNotEmpty
	}
	if len(in.Password) < 6 || len(in.Password) > 32 {
		return errorx.ErrPasswordLengthInvalid
	}
	return nil
}
